﻿/************************************************************************
 * 项目名称 :  Lm.Core.Common.Util  
 * 项目描述 :     
 * 类 名 称 :  Frame
 * 版 本 号 :  v1.0.0.0 
 * 说    明 :     
 * 作    者 :  Lewis
 * 创建时间 :  2022/4/13 11:31:09
 * 更新时间 :  2022/4/13 11:31:09
************************************************************************/

using System.Runtime.InteropServices;

namespace Modules.Units
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public class Frame : FrameBase
    {


        public ushort STX;  //帧头


        public ushort ADDR; //地址

        public ushort CMD;  //命令

        public uint LEN;  //数据长度

        public byte PC;     //奇偶校验

        public short CRC;  //校验

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
        public byte[] DATA;  //数组

        public int setBuffer(byte[] buffer)
        {
            int headlen = Marshal.SizeOf(STX) + Marshal.SizeOf(ADDR) + Marshal.SizeOf(CMD) + Marshal.SizeOf(LEN) + Marshal.SizeOf(PC) + Marshal.SizeOf(CRC);
            if (buffer == null) return -1;
            if (buffer.Length <= headlen) return -1;
            Frame _frm = new Frame();
            _frm = UtilHelper.BytesToStuct(buffer, typeof(Frame)) as Frame;
            this.STX = _frm.STX;
            this.ADDR = _frm.ADDR;
            this.CMD = _frm.CMD;
            this.LEN = _frm.LEN;
            this.PC = _frm.PC;
            this.CRC = _frm.CRC;
            DATA = new byte[LEN];
            Array.Copy(buffer, headlen, DATA, 0, LEN);
            return headlen + LEN != buffer.Length ? 0 : 1;
        }

        public byte[] getBuffer()
        {
            //byte[] buf = StructUtil.StructToBytes(this);
            int headlen = Marshal.SizeOf(STX) + Marshal.SizeOf(ADDR) + Marshal.SizeOf(CMD) + Marshal.SizeOf(LEN) + Marshal.SizeOf(PC) + Marshal.SizeOf(CRC);
            byte[] buf = new byte[LEN + headlen];
            byte[] head = UtilHelper.StructToBytes(this);
            Array.Copy(head, 0, buf, 0, headlen);
            Array.Copy(DATA, 0, buf, headlen, LEN);
            return buf;
        }

        public void checkSum() //计算校验值
        {
            CRC = 0x0000;
            short value = 0;
            value += (short)(0x00FF & CMD);
            value += (short)(0x00FF & (CMD >> 8));
            value += (short)(0x00FF & ADDR);
            value += (short)(0x00FF & ADDR >> 8);
            value += (short)(0x00FF & LEN);
            value += (short)(0x00FF & (LEN >> 8));
            value += (short)(0x00FF & (LEN >> 16));
            value += (short)(0x00FF & (LEN >> 24));
            value += (short)(0x00FF & PC);
            if (DATA != null)
                foreach (byte b in DATA)
                    value += (short)(0x00FF & b);
            CRC = (short)~value;
        }
    }
}
